package com.wzk.travelspringboot.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzk.travelspringboot.dao.ScenicDAO;
import com.wzk.travelspringboot.dao.TicketOrderDAO;
import com.wzk.travelspringboot.dao.UserDAO;
import com.wzk.travelspringboot.dto.OrderPayDTO;
import com.wzk.travelspringboot.dto.Result;
import com.wzk.travelspringboot.dto.TicketOrderDTO;
import com.wzk.travelspringboot.entity.Scenic;
import com.wzk.travelspringboot.entity.TicketOrder;
import com.wzk.travelspringboot.entity.User;
import com.wzk.travelspringboot.service.TicketOrderService;
import com.wzk.travelspringboot.utils.TDCodeUtil;
import com.wzk.travelspringboot.vo.ScenicOrderVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

/**
 * @Author: WangZiKang
 * @Date: 2025/1/19 16:20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TicketOrderServiceImpl extends ServiceImpl<TicketOrderDAO, TicketOrder> implements TicketOrderService {

    public static final Logger logger = Logger.getLogger(TicketOrderServiceImpl.class.getName());

    private final TDCodeUtil tdCodeUtil;

    private final UserDAO userDAO;

    private final ScenicDAO scenicDAO;

    private final TicketOrderDAO ticketOrderDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result createOrder(TicketOrderDTO dto) {
        //1.校验用户是否存在
        User user = userDAO.selectById(dto.getUserId());
        if (user == null || user.getState() != 1){
            return Result.failed("用户不存在或状态异常");
        }
        //2.查询景区数据
        Scenic scenic = scenicDAO.selectById(dto.getScenicId());
        if (scenic == null){
            return Result.failed("该景区不存在");
        }
        //3.创建订单并保存
        String orderNumber = RandomUtil.randomString(20);
        TicketOrder ticketOrder = new TicketOrder();
        ticketOrder.setOrderNumber(orderNumber);
        ticketOrder.setUsed(false);
        ticketOrder.setNumber(1);
        ticketOrder.setTotalAmount(scenic.getTicketPrice());
        ticketOrder.setState(1);
        ticketOrder.setUserId(user.getId());
        ticketOrder.setScenicId(scenic.getId());
        ticketOrder.setCreateTime(LocalDateTime.now());
        ticketOrder.setUpdateTime(LocalDateTime.now());
        //4.生成二维码并保存路径
        String codeUrl = tdCodeUtil.getTCode(orderNumber);
        ticketOrder.setTCode(codeUrl);
        boolean b = save(ticketOrder);
        if (!b){
            return Result.failed("创建订单失败！请待会重试");
        }
        return Result.success("订单创建成功！请支付",orderNumber);
    }

    @Override
    public Result changeOrderStatus(OrderPayDTO dto) {
        //1.判断这条订单是否存在
        TicketOrder to = ticketOrderDAO.getByOrderNumber(dto.getOrderNumber());
        if (to == null){
            return Result.failed("该订单不存在!");
        }
        if (to.getUsed() == true){
            return Result.failed("该订单已经使用");
        }
        if (to.getState() != 1){
            return Result.failed("订单已支付或已取消");
        }
        //2.修改订单状态
        int i = ticketOrderDAO.changeOrderStatus(dto.getOrderNumber(), dto.getState());
        if (i <= 0){
            return Result.failed("订单支付失败!请联系管理员");
        }
        return Result.success("订单支付成功",dto.getState());
    }

    @Override
    public Result queryOrderByUserId(Long aLong) {
        //1.查询所有订单
        List<TicketOrder> to = ticketOrderDAO.queryOrderByUserId(aLong);
        //2.判断是否为空
        if (to.isEmpty()){
            return Result.success("加载成功！", Collections.emptyList());
        }
        //3.封装vo
        ArrayList<ScenicOrderVO> vos = new ArrayList<>(to.size());
        for (TicketOrder ticketOrder : to) {
            ScenicOrderVO vo = convertToVO(ticketOrder);
            if (vo != null) {
                vos.add(vo);
            }
        }
        //4.返回结果
        return Result.success("数据加载成功",vos);
    }

    @Override
    public Result cancelOrder(String orderNumber) {
        //1.查询该订单判断状态
        TicketOrder to = ticketOrderDAO.getByOrderNumber(orderNumber);
        if (to == null){
            return Result.failed("订单不存在");
        }
        if (to.getState() == 2){
            return Result.failed("该订单已取消");
        }
        if (to.getUsed()){
            return Result.failed("订单已经使用无法取消");
        }
        //2.修改状态为已取消
        int i = ticketOrderDAO.changeOrderStatus(orderNumber, 2);
        if (i <= 0){
            return Result.failed("取消订单失败！请联系管理");
        }
        return Result.success("取消成功");
    }

    @Override
    public Result usedTicket(String on) {
        //1.查询该订单判断状态
        TicketOrder to = ticketOrderDAO.getByOrderNumber(on);
        if (to == null){
            return Result.failed("不存在该门票");
        }

        if (to.getState() != 3){
            return Result.failed("该订单还未支付");
        }

        if (to.getUsed()){
            return Result.failed("该门票已经被核销了");
        }
        //2.修改门票状态
        int i = ticketOrderDAO.changeOrderUsed(on);
        if (i <= 0){
            return Result.failed("核销门票失败!出现未知错误请联系管理");
        }
        return Result.success("核销成功！");
    }

    @Override
    public Result searchTicketOrder(com.wzk.travelspringboot.controller.admin.dto.TicketOrderDTO dto) {
        //1.判断景区的名称是否有
        if (dto.getScenicName() == null){

        }
        return null;
    }
    
    @Override
    public Result queryOrdersWithScenicName(Integer pageNum, Integer pageSize) {
        // 1. 分页查询订单数据
        Page<TicketOrder> page = new Page<>(pageNum, pageSize);
        Page<TicketOrder> orderPage = page(page);
        List<TicketOrder> orderList = orderPage.getRecords();
        
        // 2. 如果订单列表为空，返回空结果
        if (orderList.isEmpty()) {
            return Result.success(new Page<ScenicOrderVO>());
        }
        
        // 3. 关联景区信息并创建VO对象
        List<ScenicOrderVO> voList = new ArrayList<>(orderList.size());
        
        for (TicketOrder order : orderList) {
            ScenicOrderVO vo = convertToVO(order);
            if (vo != null) {
                voList.add(vo);
            }
        }
        
        // 4. 创建返回的分页对象
        Page<ScenicOrderVO> voPage = new Page<>(pageNum, pageSize, orderPage.getTotal());
        voPage.setRecords(voList);
        
        return Result.success(voPage);
    }
    
    @Override
    public ScenicOrderVO convertToVO(TicketOrder order) {
        if (order == null) {
            return null;
        }
        
        // 查询景区信息
        Scenic scenic = scenicDAO.selectById(order.getScenicId());
        if (scenic == null) {
            // 如果景区不存在，返回基本订单信息，设置景区名称为"未知景区"
            ScenicOrderVO vo = new ScenicOrderVO();
            vo.setOrderNumber(order.getOrderNumber());
            vo.setScenicId(order.getScenicId());
            vo.setState(order.getState());
            vo.setUsed(order.getUsed());
            vo.setTotalAmount(order.getTotalAmount());
            vo.setTCode(order.getTCode());
            vo.setCreateTime(order.getCreateTime());
            vo.setScenicName("未知景区");
            return vo;
        }
        
        // 创建并填充VO对象
        ScenicOrderVO vo = new ScenicOrderVO();
        vo.setOrderNumber(order.getOrderNumber());
        vo.setScenicId(order.getScenicId());
        vo.setState(order.getState());
        vo.setUsed(order.getUsed());
        vo.setTotalAmount(order.getTotalAmount());
        vo.setTCode(order.getTCode());
        vo.setCreateTime(order.getCreateTime());
        vo.setScenicName(scenic.getName());
        
        return vo;
    }
}
